from contrib import irclib
import time
import string

class IrcClient(object):
    def __init__(self, nick, server):
        self.dispatchers = []

        s = server.split(':')
        self.nick = nick
        self.host = s[0]
        self.port = int(s[1])
        self.channel = s[2]
        
        self.nicklist = []
        self.topic = ''
        self.isinchannel = False

        self.irc = irclib.IRC()
        self.irc.add_global_handler('topic', self._topic, 1000)
        self.irc.add_global_handler('join', self._join, 1000)
        self.irc.add_global_handler('namreply', self._namreply, 1000)
        self.irc.add_global_handler('pubmsg', self._pubmsg, 1000)
        self.irc.add_global_handler('privmsg', self._privmsg, 1000)
        self.irc.add_global_handler('action', self._action, 1000)
        self.irc.add_global_handler('nick', self._nick, 1000)
        self.irc.add_global_handler('part', self._quit, 1000)
        self.irc.add_global_handler('quit', self._quit, 1000)

        self.server = self.irc.server()

    def connect(self):
        self.dispatch('connect', (self.host))
        self.server.connect(self.host, self.port, self.nick)
        time.sleep(2)
        self.irc.process_once()
        self.server.join(self.channel)
        self.irc.process_once()

    def disconnect(self):
        self.server.disconnect('FGS rulz')
        self.dispatch('disconnect', (self.host))

    def join(self, channel):
        self.server.part(self.channel)
        self.irc.process_once()
        
        self.nicklist = []
        self.topic = ''
        self.isinchannel = False

        self.channel = channel
        self.server.join(channel)
        self.irc.process_once()

    def process(self):
        self.irc.process_once()

    def add_dispatcher(self, dispatcher):
        self.dispatchers.append(dispatcher)
        
    def dispatch(self, event, args = None):
        for dispatcher in self.dispatchers:
            dispatcher(event, args)

    def send(self, msg):
        cmd = msg.split(' ')
        if (cmd[0] == '/me'):
            msg = msg.lstrip('/me').lstrip(' ')
            self.server.action(self.channel, msg)
            self.dispatch('action', [self.nick, msg])
        elif (cmd[0] == '/join'):
            if (len(cmd) == 2):
                self.join(cmd[1])
            else:
                self.dispatch('privmsg', ['#', 'syntax: /join CHANNEL'])
        else:
            self.server.send_raw("PRIVMSG %s :%s" % (self.channel, msg))
            self.dispatch('pubmsg', [self.nick, msg])

    def _join(self, c, e):
        self.isinchannel = True
        nick = e.source().split('!')[0]
        self.nicklist.append(nick)
        self.dispatch('join', [nick, e.target()])

    def _action(self, c, e):
        nick = e.source().split('!')[0]
        msg = e.arguments()[0]
        self.dispatch('action', [nick, msg])

    def _namreply(self, c, e):
        self.nicklist = string.split(e.arguments()[2])
        self.nicklist.sort()
        self.dispatch('namreply')
        
    def _topic(self, c, e):
        if len(e.arguments()) > 1:
            self.topic = e.arguments()[1]
        else:
            self.topic = e.arguments()[0]
        self.dispatch('topic', [self.topic])

    def _pubmsg(self, c, e):
        nick = e.source().split('!')[0]
        msg = e.arguments()[0]
        self.dispatch('pubmsg', [nick, msg])
        
    def _privmsg(self, c, e):
        nick = e.source().split('!')[0]
        msg = e.arguments()[0]
        self.dispatch('privmsg', [nick, msg])
        
    def _nick(self, c, e):
        srcnick = e.source().split('!')[0]
        newnick = e.target()
        try:
            self.nicklist.remove(srcnick)
        except ValueError:
            ""
        self.nicklist.append(newnick)
        self.nicklist.sort()
        self.dispatch('nick', [srcnick, newnick])

    def _quit(self, c, e):
        nick = e.source().split('!')[0]
        try:
            self.nicklist.remove(nick)
        except ValueError:
            ""
        self.dispatch('quit', [nick])


